﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;

namespace MyHome.Server.PluginBase
{
    /// <summary>
    /// Abstract base class for all input plugins providing some generic implementation.
    /// </summary>
    /// <typeparam name="T">The type of data generated from this plugin</typeparam>
    public abstract class InputPlugin<T> : Plugin, IInputPlugin<T>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="InputPlugin{T}"/> class.
        /// </summary>
        protected InputPlugin()
            : base()
        {
            InputChanged += InputPlugin_InputChanged;
        }

        /// <summary>
        /// Occurs when new input data is available.
        /// </summary>
        public event EventHandler<ValueChangedEventArgs<T>> InputChanged;

        /// <summary>
        /// Gets the last value of data that was generated by this plugin.
        /// </summary>
        /// <value>
        /// The last value.
        /// </value>
        public T LastValue { get; private set; }

        /// <summary>
        /// Gets the type of the plugin.
        /// </summary>
        /// <value>
        /// <see cref="PluginType.Input"/>
        /// </value>
        public override PluginType PluginType
        {
            get { return PluginType.Input; }
        }

        /// <summary>
        /// Call this method when new data is available.
        /// This will raise the InputChanged event.
        /// </summary>
        /// <param name="newValue">The new value.</param>
        protected void OnNewValue(T newValue)
        {
            Trace.TraceInformation("{0} \"{1}\", Id: {2} has new input: {3}", PluginType.ToString(), this, Id, newValue);
            InputChanged(this, new ValueChangedEventArgs<T>(LastValue, newValue));
        }

        private void InputPlugin_InputChanged(object sender, ValueChangedEventArgs<T> e)
        {
            LastValue = e.NewValue;
        }
    }
}